home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Tools & Apps / Testing & Debugging / Robix V1.0 / JG_kernel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-21  |  7.6 KB  |  222 lines  |  [TEXT/MPS ]

  1. /*
  2. *
  3. * Copyright © 1991, Apple Computer, Inc.
  4. *
  5. * by Rob Glanville
  6. *
  7. * 8 May 91
  8. *
  9. * JG_kernel.c - A simple kernel for controlling the John Galt Ethernet cards
  10. * (NOTE: John Galt is some fictional character that nobody cares about)
  11. *
  12. */
  13.  
  14. #pragma On (Constants_in_code)
  15.  
  16. #define    UBYTE        unsigned char
  17. #define    UWORD        unsigned short
  18. #define    ULONG        unsigned long
  19.  
  20. #define    PBYTE        *(unsigned char *)    /* Used for physical address casting */
  21. #define    PWORD        *(unsigned short *)    /* Used for physical address casting */
  22. #define    PLONG        *(unsigned long *)    /* Used for physical address casting */
  23.  
  24. /* Flag bits */
  25. #define F_ready            0x80            /* Ready                            */
  26. #define F_datachain        0x40            /* DataChain                        */
  27. #define F_update        0x20            /* Update                            */
  28. #define F_interrupt        0x10            /* Interrupt                        */
  29. #define F_timer            0x08            /* TimerInt                            */
  30. #define F_aborted        0x04            /* Aborted                            */
  31. #define F_overrun        0x02            /* Overrun                            */
  32. #define F_size            0x01            /* 0=byte, 1=word                    */
  33.  
  34. #define    ItFeelsGood        0xfffffff    /* Forever flag                            */
  35. #define    Null            0x0000000
  36. #define    True            0xfffffff
  37. #define False            0x0000000
  38. #define Byte            0x00        /* Byte indicator                        */
  39. #define Word            0x01        /* Word indicator                        */
  40. #define    Full            0xff
  41. #define Empty            0x00
  42. #define Vectors            0x0000000    /* Start of interrupt vectors            */
  43. #define    Command            0x0000400    /* Start of fixed command buffer        */
  44. #define    Flags            0x0000401    /* Flags                                */
  45. #define    Count            0x0000402    /* Count                                */
  46. #define    Address            0x0000404    /* Address                                */
  47. #define    TDA                0x0000410    /* Transmit descriptor area                */
  48. #define    RDA                0x0000420    /* Receive descriptor area                */
  49. #define    RRA                0x0000430    /* Receive descriptor area                */
  50. #define    CDA                0x0000440    /* CAM descriptor area                    */
  51.  
  52. #define Null            0x00
  53.  
  54. /************************************* Defines ***********************************************/
  55.  
  56. #define SONIC        0x00900000
  57. #define ENetAddress    0x00700000
  58. #define EnetAdr0    0x00700003 /* This order looks weird but thats the way */
  59. #define EnetAdr1    0x00700001 /* SONIC likes it */
  60. #define EnetAdr2    0x00700007
  61. #define EnetAdr3    0x00700005
  62. #define EnetAdr4    0x0070000B
  63. #define EnetAdr5    0x00700009
  64.  
  65. /************************************* Variables *********************************************/
  66.  
  67. UWORD TOPOFDATA; /* DO NOT MOVE OR REMOVE!!! This MUST be first to adjust the A5 address register */
  68.  
  69. UBYTE command;
  70. UBYTE flags;
  71. UWORD count;
  72. ULONG address;
  73. UBYTE size;
  74.  
  75. /************************************* Routines **********************************************/
  76.  
  77. void DoConfiguration() {
  78.     UWORD intStatus;
  79.     ULONG timer;
  80.     PLONG 0x4e4 = 'Conf';
  81.     PWORD 0x900008 = 0x0000;    /* Mask all interrupts */
  82.     PWORD 0x90000A = 0x7FFF;    /* Clear all interrupts */
  83.     PWORD 0x900000 = 0x0085;    /* Reset and stop operations */
  84.     PWORD 0x900002 = 0x0B03;    /* Set the configuration register */
  85.     PWORD 0x900000 = 0x0000;    /* Remove the reset, stop operations */
  86.     PWORD CDA = 0x0000;            /* Set the CAM entry pointer */
  87.     PWORD (CDA + 2) = (PBYTE EnetAdr0 << 8) + (PBYTE EnetAdr1);
  88.     PWORD (CDA + 4) = (PBYTE EnetAdr2 << 8) + (PBYTE EnetAdr3);
  89.     PWORD (CDA + 6) = (PBYTE EnetAdr4 << 8) + (PBYTE EnetAdr5);
  90.     PWORD (CDA + 8) = 0x0001;    /* Set the CAM descriptor count */
  91.     PWORD 0x900028 = 0x0000;    /* Set upper pointer */
  92.     PWORD 0x90004C = CDA;        /* Set lower pointer */
  93.     PWORD 0x90004E = 0x0001;    /* Set descriptor count */
  94.     PWORD 0x900000 = 0x0200;    /* Set load CAM command */
  95.     timer = 0x10000; /* More than enough time */
  96.     do {
  97.         intStatus = PWORD 0x90000A; /* Read the interrupt status */
  98.         } while (((intStatus & 0x1000) != 0x1000) && (--timer));
  99.     PLONG 0x4e8 = timer;
  100.     }
  101.  
  102. void DoTransmit() {
  103.     UWORD intStatus;
  104.     ULONG timer;
  105.     PWORD TDA       = 0x0000;        /* Set status                */
  106.     PWORD (TDA + 2) = 0x5000;        /* Set configuration        */
  107.     PWORD (TDA + 4) = count;        /* Set packet length        */
  108.     PWORD (TDA + 6) = 0x0001;        /* Set fragment count        */
  109.     PWORD (TDA + 8) = address;        /* Set lower address        */
  110.     PWORD (TDA + 10)= 0x0000;        /* Set upper address        */
  111.     PWORD (TDA + 12)= count;        /* Set fragment length        */
  112.     PWORD (TDA + 14)= 0x0001;        /* Set for no link            */
  113.     PWORD 0x90000C  = 0x0000;        /* Set upper address        */
  114.     PWORD 0x90000E  = TDA;            /* Set Lower address        */
  115.     PWORD 0x900000  = 0x0002;        /* Start transmission        */
  116.     timer = 0x80000; /* More than enough time */
  117.     do {
  118.         intStatus = PWORD 0x90000A; /* Read the interrupt status */
  119.         } while (((intStatus & 0x0200) != 0x0200) && (--timer));
  120.     PWORD 0x90000A = 0x0200;        /* Clear the interrupt        */
  121.     }
  122.  
  123. void DoReadStatus() {
  124.     PWORD Count      = PWORD 0x90000A;/* Get interrupt status    */
  125.     PWORD Address    = PWORD 0x900004;/* Get receive status        */
  126.     PWORD (Address+2)= PWORD 0x900006;/* Get transmit status    */
  127.     }
  128.  
  129. void DoReceive() {    
  130.     UWORD intStatus;
  131.     ULONG timer;
  132.     /* Build the receiver resource area                                */
  133.     PWORD (RRA    )  = address; /* Set lower address                */
  134.     PWORD (RRA + 2)  = 0x0000;  /* Set upper address                */
  135.     PWORD (RRA + 4)  = count;    /* Set lower length                    */
  136.     PWORD (RRA + 6)  = 0x0000;  /* Set upper length                    */
  137.     /* Build receiver descriptor                                    */
  138.     PWORD (RDA    )  = 0x0000;  /* Set status                        */
  139.     PWORD (RDA + 2)  = 0x0000;  /* Set packet length                */
  140.     PWORD (RDA + 4)  = 0x0000;  /* Set lower address                */
  141.     PWORD (RDA + 6)  = 0x0000;  /* Set upper address                */
  142.     PWORD (RDA + 8)  = 0x0000;  /* Set Sequence number                */
  143.     PWORD (RDA + 10) = 0x0001;  /* Set link                            */
  144.     PWORD (RDA + 12) = 0xffff;  /* Set in use                        */
  145.     /* Load registers and get read for reception                    */
  146.     PWORD 0x90001A = 0x0000;     /* Set upper address                */
  147.     PWORD 0x90001C = RDA;         /* Set Lower address                */
  148.     PWORD 0x900028 = 0x0000;     /* Set upper address                */
  149.     PWORD 0x90002A = RRA;        /* Set Resource start address        */
  150.     PWORD 0x90002C = RRA+4;      /* Set Resource end address            */
  151.     PWORD 0x90002E = RRA;        /* Set Resource read register        */
  152.     PWORD 0x900030 = RRA+4;      /* Set Resource write register        */
  153.     PWORD 0x900056 = 0x0000;     /* Set Receive sequence counter        */
  154.     PWORD 0x900000 = 0x0100;    /* Read RRA                            */
  155.     PWORD 0x900000 = 0x0008;    /* Start receiving                    */
  156.     timer = 0x800000; /* More than enough time */
  157.     do {
  158.         intStatus = PWORD 0x90000A; /* Read the interrupt status */
  159.         } while (((intStatus & 0x0400) != 0x0400) && (--timer));
  160.     PWORD 0x90000A = 0x0400;        /* Clear the interrupt        */
  161.     }
  162.  
  163. void DoCommand() {
  164.     while (((flags = PBYTE Flags) & F_ready) == Null);
  165.     command = PBYTE Command;
  166.     count = PWORD Count;
  167.     address = PLONG Address;
  168.     switch (command) {
  169.         case 0x01 : /* Configure Ethernet */
  170.             DoConfiguration();
  171.             PLONG 0x4d0 = 'Cdon';
  172.             break;
  173.         case 0x02 : /* Transmit packet */
  174.             DoTransmit();
  175.             PLONG 0x4d0 = 'DoTx';
  176.             break;
  177.         case 0x03 : /* Read Status */
  178.             DoReadStatus();
  179.             PLONG 0x4d0 = 'DoSt';
  180.             break;
  181.         case 0x04 : /* Receive packet */
  182.             DoReceive();
  183.             PLONG 0x4d0 = 'DoRx';
  184.             break;
  185.         case 0x81 : /* Read Data */
  186.             if (PBYTE Flags & F_size) size = Word;
  187.             else size = Byte;
  188.             if (size == Word) PWORD Count = PWORD address;
  189.             else PBYTE Count = PBYTE address;
  190.             PLONG 0x4d0 = 'Read';
  191.             break;
  192.         case 0x82 : /* Write data */
  193.             if (PBYTE Flags & F_size) size = Word;
  194.             else size = Byte;
  195.             if (size == Word) PWORD address = count;
  196.             else PBYTE address = count;
  197.             PLONG 0x4d0 = 'Writ';
  198.             break;
  199.         default:
  200.             PLONG 0x4d0 = 'Dflt';
  201.             break;
  202.         }
  203.     PBYTE Flags = (flags & 0x7f); /* Clear ready bit */
  204.     }
  205.  
  206. void InitializeVectors() {
  207.     /* Initialize the interrupt vectors */
  208.     }
  209.  
  210. COMMANDLOOP() {
  211.     TOPOFDATA = 'RG'; /* Lets just mark it with something unique */
  212.     InitializeVectors();
  213.     DoConfiguration();
  214.     PBYTE Command = Null; /* Clear the command */
  215.     PBYTE Flags   = Null; /* Clear the flags   */
  216.     PWORD Count   = Null; /* Clear the count   */
  217.     PLONG Address = Null; /* Clear the address */
  218.     PLONG 0x4f0 = 'Loop';
  219.     while (ItFeelsGood) {
  220.         DoCommand();
  221.         }
  222.     }